// common/services/network/network_interceptor.dart
import 'package:dio/dio.dart' hide Response;
import 'package:flutter/foundation.dart';
import 'package:get/get.dart';
import 'package:dio/dio.dart' as dio show Response;
import '../storage_service.dart';

/// 认证拦截器 - 自动添加Token
class AuthInterceptor extends Interceptor {
  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
    // 获取存储的token
    final storageService = Get.find<StorageService>();
    final token = storageService.getUserToken();
    
    if (token.isNotEmpty) {
      options.headers['Authorization'] = 'Bearer $token';
    }
    
    super.onRequest(options, handler);
  }
  
  @override
  void onError(DioException err, ErrorInterceptorHandler handler) {
    // 处理401未授权错误
    if (err.response?.statusCode == 401) {
      final storageService = Get.find<StorageService>();
      storageService.clearUserData(); // 清除用户数据
      
      // 可以在这里触发跳转到登录页面
      // Get.offAllNamed(RouteNames.systemLogin);
    }
    
    super.onError(err, handler);
  }
}

/// 重试拦截器 - 自动重试失败的请求
class RetryInterceptor extends Interceptor {
  final int maxRetries;
  final int retryDelay;
  
  RetryInterceptor({
    this.maxRetries = 3,
    this.retryDelay = 1000,
  });
  
  @override
  void onError(DioException err, ErrorInterceptorHandler handler) async {
    final extra = err.requestOptions.extra;
    final retryCount = extra['retryCount'] ?? 0;
    
    // 判断是否需要重试
    if (retryCount < maxRetries && _shouldRetry(err)) {
      extra['retryCount'] = retryCount + 1;
      
      // 延迟后重试
      await Future.delayed(Duration(milliseconds: retryDelay));
      
      try {
        final dio = Dio();
        final response = await dio.fetch(err.requestOptions);
        handler.resolve(response);
        return;
      } catch (e) {
        // 重试失败，继续原有错误处理
      }
    }
    
    super.onError(err, handler);
  }
  
  /// 判断是否应该重试
  bool _shouldRetry(DioException err) {
    switch (err.type) {
      case DioExceptionType.connectionTimeout:
      case DioExceptionType.sendTimeout:
      case DioExceptionType.receiveTimeout:
      case DioExceptionType.connectionError:
        return true;
      case DioExceptionType.badResponse:
        // 5xx服务器错误可以重试
        final statusCode = err.response?.statusCode;
        return statusCode != null && statusCode >= 500;
      default:
        return false;
    }
  }
}

/// 日志拦截器 - 打印请求和响应信息
class LoggingInterceptor extends Interceptor {
  final bool logRequest;
  final bool logResponse;
  final bool logError;
  
  LoggingInterceptor({
    this.logRequest = true,
    this.logResponse = true,
    this.logError = true,
  });
  
  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
    if (logRequest) {
      // 构建完整的URL
      final fullUrl = '${options.baseUrl}${options.path}';
      debugPrint('🚀 REQUEST[${options.method}] => FULL_URL: $fullUrl');
      debugPrint('   BaseUrl: ${options.baseUrl}');
      debugPrint('   Path: ${options.path}');
      debugPrint('   Headers: ${options.headers}');
      if (options.data != null) {
        debugPrint('   Data: ${options.data}');
      }
      if (options.queryParameters.isNotEmpty) {
        debugPrint('   QueryParameters: ${options.queryParameters}');
      }
      debugPrint('   ConnectTimeout: ${options.connectTimeout}');
      debugPrint('   ReceiveTimeout: ${options.receiveTimeout}');
    }
    super.onRequest(options, handler);
  }
  
  @override
  void onResponse(dio.Response response, ResponseInterceptorHandler handler) {
    if (logResponse) {
      final fullUrl = '${response.requestOptions.baseUrl}${response.requestOptions.path}';
      debugPrint('✅ RESPONSE[${response.statusCode}] => FULL_URL: $fullUrl');
      debugPrint('   StatusCode: ${response.statusCode}');
      debugPrint('   StatusMessage: ${response.statusMessage}');
      debugPrint('   Headers: ${response.headers}');
      debugPrint('   Data: ${response.data}');
      debugPrint('   ResponseTime: ${DateTime.now().millisecondsSinceEpoch}ms');
    }
    super.onResponse(response, handler);
  }
  
  @override
  void onError(DioException err, ErrorInterceptorHandler handler) {
    if (logError) {
      final fullUrl = '${err.requestOptions.baseUrl}${err.requestOptions.path}';
      debugPrint('❌ ERROR[${err.response?.statusCode}] => FULL_URL: $fullUrl');
      debugPrint('   BaseUrl: ${err.requestOptions.baseUrl}');
      debugPrint('   Path: ${err.requestOptions.path}');
      debugPrint('   ErrorType: ${err.type}');
      debugPrint('   Message: ${err.message}');
      if (err.response != null) {
        debugPrint('   StatusCode: ${err.response!.statusCode}');
        debugPrint('   StatusMessage: ${err.response!.statusMessage}');
        debugPrint('   Response Headers: ${err.response!.headers}');
        if (err.response!.data != null) {
          debugPrint('   Error Data: ${err.response!.data}');
        }
      }
      debugPrint('   StackTrace: ${err.stackTrace}');
    }
    super.onError(err, handler);
  }
}

/// 缓存拦截器 - 简单的内存缓存实现
class CacheInterceptor extends Interceptor {
  final Map<String, CacheItem> _cache = {};
  final int maxCacheTime; // 缓存时间（毫秒）
  
  CacheInterceptor({this.maxCacheTime = 300000}); // 默认5分钟
  
  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
    // 只对GET请求进行缓存
    if (options.method.toUpperCase() == 'GET') {
      final key = _generateCacheKey(options);
      final cacheItem = _cache[key];
      
      if (cacheItem != null && !cacheItem.isExpired) {
        // 返回缓存的响应
        handler.resolve(cacheItem.response);
        return;
      }
    }
    
    super.onRequest(options, handler);
  }
  
  @override
  void onResponse(dio.Response response, ResponseInterceptorHandler handler) {
    // 缓存GET请求的成功响应
    if (response.requestOptions.method.toUpperCase() == 'GET' && 
        response.statusCode == 200) {
      final key = _generateCacheKey(response.requestOptions);
      _cache[key] = CacheItem(response, DateTime.now().millisecondsSinceEpoch + maxCacheTime);
    }
    
    super.onResponse(response, handler);
  }
  
  String _generateCacheKey(RequestOptions options) {
    return '${options.method}_${options.path}_${options.queryParameters.toString()}';
  }
  
  void clearCache() {
    _cache.clear();
  }
}

class CacheItem {
  final dio.Response response;
  final int expireTime;
  
  CacheItem(this.response, this.expireTime);
  
  bool get isExpired => DateTime.now().millisecondsSinceEpoch > expireTime;
}
